import { listenRequestClientIdQueueFile } from "./listenRequestClientIdQueue"
import { v4 } from 'uuid'
import { join } from "path"

import { expressFactory } from './expressFactory'
import { createLogger } from '@nodejs/logger'
import cluster from 'cluster'
import { cpus, homedir } from 'os'
import { ensureDir } from "fs-extra"
import { readJson, saveJson } from "./utils"
import { listenRequestQueueFile } from "./listenRequestQueue"
export async function client(root: string, name: string, hasServer: boolean = false) {
    const logger = await createLogger('main')
    const isDev = process.env.NODE_ENV === 'development'
    const home = homedir()
    if (cluster.isPrimary && !isDev) {
        for (let i = 0; i < cpus().length; i++) {
            cluster.fork({ INDEX: i })
        }
        cluster.on('exit', (worker, code, signal) => {
            logger.info(`Worker ${worker.process.pid} died with code: ${code}, and signal: ${signal}`);
            logger.info('Starting a new worker');
            cluster.fork();
        });
    } else {
        const jsonFile = `${process.env.INDEX || 0}.json`
        await ensureDir(join(home, 'sker', name))
        const configPath = join(home, 'sker', name, jsonFile)
        const config = await readJson(configPath)
        const uuid = config.uuid || v4()
        process.env.CLIENT_ID = uuid;
        await saveJson(configPath, { uuid })
        const closers: Function[] = [];
        const closer1 = await listenRequestClientIdQueueFile(uuid, name, join(root, 'dist'))
        closers.push(closer1)
        const closer2 = await listenRequestQueueFile(uuid, name, join(root, 'dist'))
        closers.push(closer2)
        if (hasServer) {
            const app = await expressFactory(uuid, false)
            const closer3 = await app.listen()
            closers.push(closer3)
            logger.info(`Server started on port ${process.env.HOST} ${process.env.PORT || 3000}`)
        }
        process.on('exit', async () => {
            await Promise.all(closers.map(c => c()))
        })
        return uuid;
    }
}
